package com.chen.service.impl;

import cn.hutool.json.JSONUtil;
import com.chen.common.constant.ElasticSearchConstant;
import com.chen.common.result.PageResult;
import com.chen.common.utils.ElasticSearchUtil;
import com.chen.popj.dto.ProblemDTO;
import com.chen.popj.dto.ProblemPageQueryDTO;
import com.chen.popj.vo.ProblemListVO;
import com.chen.service.ElasticSearchService;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;

@Service
public class ElasticSearchServiceImpl implements ElasticSearchService {

    @Autowired
    RestHighLevelClient restHighLevelClient;

    @Override
    public PageResult<ProblemListVO> queryProblemListVOByTitle(String index, ProblemPageQueryDTO problemPageQueryDTO) {
        SearchRequest searchRequest = new SearchRequest(index);
        int page = problemPageQueryDTO.getPage(), pageSize = problemPageQueryDTO.getPageSize();
        if (!problemPageQueryDTO.getGrade().isEmpty()) {
            searchRequest.source().query(QueryBuilders.matchQuery(ElasticSearchConstant.GRADE, problemPageQueryDTO.getGrade()));
        }
        if (!problemPageQueryDTO.getTag().isEmpty()) {
            searchRequest.source().query(QueryBuilders.matchQuery(ElasticSearchConstant.TITLE, problemPageQueryDTO.getTag()));
        }
        if (problemPageQueryDTO.getTag().isEmpty() && problemPageQueryDTO.getGrade().isEmpty()) {
            searchRequest.source().query(QueryBuilders.matchAllQuery());
        }
        searchRequest.source().from((page - 1) * pageSize).size(pageSize);
        SearchResponse response = null;
        try {
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ElasticSearchUtil.handleResponse(response);
    }

    @Override
    public PageResult<ProblemListVO> queryProblemListVOById(String index, ProblemPageQueryDTO problemPageQueryDTO) {
        SearchRequest searchRequest = new SearchRequest(index);
        int page = problemPageQueryDTO.getPage(), pageSize = problemPageQueryDTO.getPageSize();

        if (!problemPageQueryDTO.getGrade().isEmpty()) {
            searchRequest.source().query(QueryBuilders.termQuery(ElasticSearchConstant.GRADE, problemPageQueryDTO.getGrade()));
        }
        if (!problemPageQueryDTO.getTag().isEmpty()) {
            searchRequest.source().query(QueryBuilders.termQuery(ElasticSearchConstant.ID, problemPageQueryDTO.getTag()));
        }
        searchRequest.source().from((page - 1) * pageSize).size(pageSize);
        SearchResponse response = null;
        try {
            response = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return ElasticSearchUtil.handleResponse(response);
    }

    @Override
    public void addProblem(ProblemDTO problemDTO) {
        ProblemListVO problemListVO = ProblemListVO.builder()
                .id(problemDTO.getId())
                .grade(problemDTO.getGrade())
                .title(problemDTO.getTitle())
                .submitNumber(0)
                .acceptedNumber(0)
                .build();
        IndexRequest indexRequest = new IndexRequest(ElasticSearchConstant.PROBLEM_LIST)
                .id(problemDTO.getId().toString());
        indexRequest.source(JSONUtil.toJsonStr(problemListVO), XContentType.JSON);
        try {
            restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}
